#include <allegro.h>
#include <cmath>
#include "main.h"

BITMAP* bufor = NULL;

int main() {
	init();
    Rectangle* frame = new Rectangle(bufor,50,50,950,550,255,255,255);
    Dynamic* pal = new Dynamic(bufor,55,200,95,400,255,255,255,0,0);
    Dynamic* pal2 = new Dynamic(bufor,905,200,945,400,255,255,255,0,0);
    Physic* ball = new Physic(bufor,125,125,150,150,255,255,255,0.7,0.7);
	while (!key[KEY_ESC]) {
		clear_to_color(bufor, makecol( 0, 0, 0 ));
        frame->draw();
        if(key[KEY_W]&&pal->show_speed(1)>-1) pal->change_speed(0,-0.01);
        if(key[KEY_S]&&pal->show_speed(1)<1) pal->change_speed(0,0.01);
        if(pal->show_speed(1)!=0)
        {
          if(pal->show_speed(1)>0) pal->change_speed(0,-0.005);
          else pal->change_speed(0,0.005);
        }
        pal->move();
        pal->drawfill();
        if(pal2->show_speed(1)>-1&&pal2->show(0,1)>ball->show(1,1)) pal2->change_speed(0,-0.01);
        if(pal2->show_speed(1)<1&&pal2->show(1,1)<ball->show(0,1)) pal2->change_speed(0,0.01);
        if(pal2->show_speed(1)!=0)
        {
          if(pal2->show_speed(1)>0) pal2->change_speed(0,-0.005);
          else pal2->change_speed(0,0.005);
        } 
        pal2->move();
        pal2->drawfill();
        ball->move();
        ball->drawfill();
        col_pr(ball,frame);
        col_pd(ball,pal);
        col_pd(ball,pal2);
        col_dr(pal,frame);
        col_dr(pal2,frame);
        blit( bufor, screen, 0, 0, 0, 0, bufor->w, bufor->h );
	}
	delete frame;
    delete pal;
    delete ball;
	deinit();
	return 0;
}
END_OF_MAIN()

void init() {
	int depth, res;
	allegro_init();
	depth = desktop_color_depth();
	if (depth == 0) depth = 32;
	set_color_depth(depth);
	res = set_gfx_mode(GFX_AUTODETECT_WINDOWED, 1000, 600, 0, 0);
	if (res != 0) {
		allegro_message(allegro_error);
		exit(-1);
	}
	install_timer();
	install_keyboard();
	install_mouse();
	bufor = create_bitmap(1000,600);
}

void deinit() {
	clear_keybuf();
}

void col_pr(Physic* object, Rectangle* colliding)
{
  enum dir direction = object->collision_in(colliding);
  if(direction != N)
  {
    float modx = 1, mody = 1; 
    direction == HOR ? modx = -1 : mody = -1;
    object->change_speed(modx,mody);
  }  
}

void col_pd(Physic* object, Dynamic* colliding)
{
  enum dir direction = object->collision_out(colliding);
  if(direction != N)
  {
    float modx = 1, mody = 1; 
    direction == HOR ? modx = -1 : mody = -1;
    object->change_speed(modx,mody);
  }  
}

void col_dr(Dynamic* object, Rectangle* colliding)
{
  enum dir direction = object->collision_in(colliding);
  if(direction != N)
  {
    float modx = 0, mody = 0; 
    direction == HOR ? modx = -2*object->show_speed(0) : mody = -2*object->show_speed(1);
    object->change_speed(modx,mody);
  }  
}

Rectangle::Rectangle(BITMAP* bufor,float x1,float y1,float x2,float y2,int c1,int c2,int c3)
{
  this->bufor=bufor;
  this->w[0][0]=x1;
  this->w[0][1]=y1;
  this->w[1][0]=x2;
  this->w[1][1]=y2;
  this->color[0]=c1;
  this->color[1]=c2;
  this->color[2]=c3;
}

enum dir Moving::collision_in(Rectangle* object)
{
  if(this->w[0][0]<=object->show(0,0)||this->w[1][0]>=object->show(1,0)) return HOR;
  if(this->w[0][1]<=object->show(0,1)||this->w[1][1]>=object->show(1,1)) return VER;
  return N;
}

enum dir Moving::collision_out(Rectangle* object)
{
  if((this->w[1][0]>object->show(0,0)&&this->w[0][0]<object->show(1,0))&&((this->w[0][1]<=object->show(1,1)&&this->w[1][1]>=object->show(0,1))||(this->w[1][1]>=object->show(0,1)&&this->w[0][1]<=object->show(1,1)))) return VER;
  if((this->w[1][1]>object->show(0,1)&&this->w[0][1]<object->show(1,1))&&((this->w[0][0]<=object->show(1,0)&&this->w[1][0]>=object->show(0,0))||(this->w[1][0]>=object->show(0,0)&&this->w[0][0]<=object->show(1,0)))) return HOR;
  return N;
}
